#ifndef __WIN_SIGNAL_H
#define __WIN_SIGNAL_H

#ifdef OS_WIN
#include <stdio.h>
#include <mutex>
#include <condition_variable>
#include <thread>
#include <forward_list>

typedef void (*signal_handler)(int);

struct w_signal {
    volatile int running;
    int signo;
    std::thread *th;
    std::mutex mutex;
    std::condition_variable cv;
    signal_handler func;

    w_signal(int signo, signal_handler func) {
        this->running = 1;

        this->signo = signo;
        this->func = func;
        this->th = new std::thread(&w_signal::on_signal, this);
    }

    void on_signal() {
        while (running) {
            std::unique_lock<std::mutex> lck(this->mutex);
            this->cv.wait(lck);

            //printf("[ on_signal ] recv signal....\n");

            this->func(this->signo);
        }
    }

    ~w_signal() {
        this->running = 0;

        if (this->th) {
            this->th->join();
            delete this->th;

            this->th = nullptr;
        }
    }
};

static std::forward_list<w_signal *> signals_;

inline int kill(pid_t pid, int signo) {
    for (auto& signal: signals_) {
        if (signal->signo == signo) {
            std::unique_lock<std::mutex> lck(signal->mutex);
            signal->cv.notify_all();
        }
    }

    return 0;
}

inline void _signal(int sig, signal_handler func) {
    w_signal *signal = new w_signal(sig, func);
    signals_.emplace_front(signal);
}

#define signal _signal
#else
#include <signal.h>
#endif

#endif
